package basicx.oop.adt


/*-*- coding:utf-8 -*-
* @Author  : ygree 
* @Time    : 2021/7/2 0:14
* @Software : IntelliJ IDEA
*/

//
// 印章类、密封类,子类类型有限的class
/**对于更复杂的ADT，你可以使用Kotlin的密封类(sealed class）来实现更复杂的定义，
密封类可以用来定义一个类似于枚举类的ADT，但你可以更灵活地控制某个子类型。
密封类可以有若干个子类，要继承密封类，这些子类必须和它定义在同一个文件里。
 */
private interface show {
    fun show(str: String)
}

private sealed class Son : show {
    override fun show(str: String) {
        println("show:$str")
    }

    class First() : Son() {
        class FirstFunction : Son() {} // ok
    }

    class Second : Son()
}

private class Third : Son() {
    class ThirdFunction : Son() {} //ok
}

private object Fourth : Son() {
    class FourthFunction : Son() {} //ok

}

private  fun main() {
//    val s: Son = Son()//无法实例化的抽象类-
    val first: Son = Son.First() as Son
    val first1: Son = Son.First()
    println("s == s1: ${first == first1}")
    val second: Son = Son.Second()
    var list = listOf<Son>(first, first1, second)
    for (v in list) {
        if (v is Son.First) {
            v.show(v.toString())
        }
    }

    when (first) {
        is Son.First -> {
        }

        is Son -> {
        }

        is Son.Second -> {

        }

        is Third -> {

        }

        is Fourth -> {

        }

        is Son.First.FirstFunction -> TODO()
        is Third.ThirdFunction -> TODO()
        is Fourth.FourthFunction -> TODO()
    }


    val openFirst: SealedOpen = OpenFirst()
    when (openFirst) {
        is SealedOpen -> {
        }

        is SealedOpen.Init -> {
        }

        is OpenFirst -> {
        }
    }
}

// 其他文件的密封类
private class OpenFirst : SealedOpen() {
}

private class OpenSecond : SealedOpen() {
}


